package utils

import (
	"sync"
	"time"

	"github.com/kataras/iris/v12"
	"github.com/kataras/iris/v12/sessions"
)

var (
	sessionManager *sessions.Sessions
	sessOnce       sync.Once
)

const (
	// SessionKeyLoginUser session id
	SessionKeyLoginUser = "SessionKeyLoginUser"
)

func getsessionins() *sessions.Sessions {
	sessOnce.Do(func() {
		sessionManager = sessions.New(
			sessions.Config{
				// Cookie string, the session's client cookie name, for example: "mysessionid"
				//
				// Defaults to "irissessionid"
				Cookie: "finego_sessionid",
				// it's time.Duration, from the time cookie is created, how long it can be alive?
				// 0 means no expire.
				// -1 means expire when browser closes
				// or set a value, like 2 hours:
				Expires: time.Hour * 2,
				// if you want to invalid cookies on different subdomains
				// of the same host, then enable it.
				// Defaults to false.
				DisableSubdomainPersistence: false,
			})
	})
	return sessionManager
}

// SetSession 设置 session 值
func SetSession(ctx iris.Context, key string, val interface{}) {
	if len(key) == 0 {
		panic("Session Key 不能为空")
	}
	if val == nil {
		return
	}
	sess := getsessionins()
	session := sess.Start(ctx)
	session.Set(key, val)
}

// GetSession 获取 session 值
func GetSession(ctx iris.Context, key string) interface{} {
	if len(key) == 0 {
		panic("Session Key 不能为空")
	}
	sess := getsessionins()
	session := sess.Start(ctx)
	return session.Get(key)
}

// DeleteSession 删除 session 值
func DeleteSession(ctx iris.Context, key string) {
	// delete a specific key
	sess := getsessionins()
	session := sess.Start(ctx)
	session.Delete(key)
}

// ClearSession 清空所有 session 值
func ClearSession(ctx iris.Context) {
	// removes all entries
	sess := getsessionins()
	session := sess.Start(ctx)
	session.Clear()
}

// RemoveExpiredSession 清空所有过期 session 值
func RemoveExpiredSession(ctx iris.Context) {
	// updates expire date with a new dat
	sess := getsessionins()
	sess.ShiftExpiration(ctx)
}

// DestroySession 销毁 session 及 cookie
func DestroySession(ctx iris.Context) {
	// destroy, removes the entire session data and cookie
	sess := getsessionins()
	sess.Destroy(ctx)
}
